﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.Core.TransactionsResponse;
using MS.InformationManagement.DAL.DocumentCenter;
using MS.InformationManagement.Support.Constants;
using Microsoft.SharePoint;
using MS.InformationManagement.Support.Enums;
using MS.InformationManagement.DAL.DTOs;

namespace MS.InformationManagement.BLL.ShippingControlTemplates
{
    public class ShippingControlTemplatesCommand : ICommandWithResponse
    {
       #region Fields

        Stack<ICommand> _commands;
        string _currentUser;
        IEnumerable<PlanillasDTO> _foundRadicadosDevueltos;
        IEnumerable<PlanillasDTO> _foundRadicadosRecibidos;
        IEnumerable<PlanillasDTO> _foundCopiasDevueltas;
        IEnumerable<PlanillasDTO> _foundCopiasRecibidas;
        IEnumerable<PlanillasDTO> _foundItemsReprogramar;
        IEnumerable<PlanillasDTO> _foundItemsDistribucion;

        #endregion

        #region Constructors

        public ShippingControlTemplatesCommand(IEnumerable<PlanillasDTO> foundRadicados)
        {
            _foundRadicadosDevueltos = foundRadicados.Where(x => x.Recibido == false && x.EsCopia == false);
            _foundCopiasDevueltas = foundRadicados.Where(x => x.Recibido == false && x.EsCopia == true);

            _foundRadicadosRecibidos = foundRadicados.Where(x => x.Recibido == true && x.EsCopia == false);
            _foundCopiasRecibidas = foundRadicados.Where(x => x.Recibido == true && x.EsCopia == true);

            _foundItemsReprogramar = foundRadicados.Where(x => x.Recibido == false && x.Reprogrmar == true);
            _foundItemsDistribucion = foundRadicados.Where(x => x.Recibido == false && x.Reprogrmar == false);
        }

        #endregion

        #region Command Methods

        public ITransactionResponse Execute()
        {
            _commands = new Stack<ICommand>();

            DeliveryFormCreationResponse documentResponse = new DeliveryFormCreationResponse();
            documentResponse.Result = false;

            try
            {
                //Actualiza el estado de los radicado a Entregado
                MarkRadicadoAsDeliveredCommand UpdateDeliveredRadicado = new MarkRadicadoAsDeliveredCommand(_foundRadicadosRecibidos);
                _commands.Push(UpdateDeliveredRadicado);
                UpdateDeliveredRadicado.Execute();

                //Actualiza el estado de las con copia de un radicado a Entregado
                MarkCopiaAsDeliveredCommand UpdateDeliveredCopia = new MarkCopiaAsDeliveredCommand(_foundRadicadosRecibidos);
                _commands.Push(UpdateDeliveredCopia);
                UpdateDeliveredCopia.Execute();

                //Actualiza los estados de un radicado a devuelto
                MarkRadicadoAsReturnedCommand UpdateReturnedRadicado = new MarkRadicadoAsReturnedCommand(_foundRadicadosDevueltos);
                _commands.Push(UpdateReturnedRadicado);
                UpdateReturnedRadicado.Execute();

                //Actualiza los estados de las con copia a devuelto
                MarkCopiaAsReturnedCommand UpdateReturnedCopia = new MarkCopiaAsReturnedCommand(_foundCopiasDevueltas);
                _commands.Push(UpdateReturnedCopia);
                UpdateReturnedCopia.Execute();

                //Crea le item para reprogramar el envio en la lista envios de correo
                CreateItemEnviosDeCorreoListCommand createItemEnviosCorreo = new CreateItemEnviosDeCorreoListCommand(_foundItemsReprogramar);
                _commands.Push(createItemEnviosCorreo);
                createItemEnviosCorreo.Execute();

                //Crea un item en la lista distribucion para devolver el radicado impreso al usuario dueño del mismo.
                CreateItemDistributionListCommand createItemDistribucion = new CreateItemDistributionListCommand(_foundItemsDistribucion);
                _commands.Push(createItemDistribucion);
                createItemDistribucion.Execute();

                //Crea el item en la lista de devolcuiones.
                CreateItemDevolucionListCommand createItemDevolucion = new CreateItemDevolucionListCommand(_foundItemsDistribucion);
                _commands.Push(createItemDevolucion);
                createItemDevolucion.Execute();


                documentResponse.Result = true;
                return documentResponse;

            }
            catch (Exception ex)
            {
                this.Undo();
                throw ex;
            }
        }

        public void Undo()
        {
            foreach (var item in _commands)
                item.Undo();
        }

        #endregion

        #region Private Methods

        private DeliveryTraceabilityEntry getDeliverEntity(EnvíoDeCorrespondencia currentEntity, string deliveryFormId, string department, SPListItem listItem)
        {
            DeliveryTraceabilityEntry logEntry = new DeliveryTraceabilityEntry();
            logEntry.Address = currentEntity.Copia.HasValue && currentEntity.Copia.Value ? listItem[CustomSiteColumns.FLD_COPY_CONTACT_ADDRESS].ToString() : currentEntity.Dirección;
            logEntry.Area = department;
            logEntry.City = currentEntity.City.Label;
            logEntry.DateTime = DateTime.Now;
            //logEntry.Department = department;
            logEntry.FormNumber = deliveryFormId;
            logEntry.To = currentEntity.Copia.HasValue && currentEntity.Copia.Value ? listItem[CustomSiteColumns.FLD_COPY_NAME].ToString() : currentEntity.RemitenteDestinatario;
            logEntry.Operation = DeliveryOperations.Enviado.ToString();
            logEntry.User = _currentUser;
            return logEntry;
        }

        #endregion
    }
}
